//
//  LBAutoContrastFilter.mm
//  OpenGLGame
//
//  Created by Nguyen Cong Huy on 12/12/12.
//  Copyright (c) 2012 UIT. All rights reserved.
//

#include <iostream>
#include "LBAutoContrastFilter.h"
#include "LBGraphics.h"



char autoContrastFragStr[] = ""
"   precision lowp float;  "
"   uniform sampler2D texture; "
"   varying vec2 vtexCoor; "
"   uniform float minColor;"
"   uniform float maxColor;"

"   float lut(float min, float max, float color){"
"       float delta = color - min;"
"       delta = delta / (max - min);"

"       delta = clamp(delta, 0.0, 1.0);"

"       return delta;"
"   }"

"   void main()"
"   {"
"       vec4 textureColor =texture2D(texture,vtexCoor);"
"       vec4 result;"
"       result.r = lut(minColor, maxColor, textureColor.r);"
"       result.g = lut(minColor, maxColor, textureColor.g);"
"       result.b = lut(minColor, maxColor, textureColor.b);"
"       result.a = textureColor.a;"
"       gl_FragColor = result;"
"   }";

LBAutoContrastFilter::LBAutoContrastFilter(){
    init(0, autoContrastFragStr);
    
    minColorUniform = program->uniformIndex("minColor");
    maxColorUniform = program->uniformIndex("maxColor");
}

void LBAutoContrastFilter::setHistogram(int* histogram){
    memcpy(&this->histogram, histogram, sizeof(int)*256);
    
    int autoThreshold = 2000;
    int pixelCount = 0;
    for (int i =0; i < 256; i++) {
        pixelCount += histogram[i];
    }
    
    int threshold = pixelCount / autoThreshold;
    bool found = false;
    
    //Find bound Max
    int i = -1;
    do {
        i++;
        found = histogram[i] > threshold;
    } while (!found && i < 255);
    int hMin = i;
    
    i = 256;
    do {
        i--;
        found = histogram[i] > threshold;
    } while (!found && i > 0);
    int hMax = i;
    
    int histogramMin = 0;
    int binSize = 1.0;
    float fMin, fMax;
    
    //Progress Again
    if (hMax > hMin) {
        fMin = (float)(histogramMin + hMin*binSize)/255;
        fMax = (float)(histogramMin + hMax*binSize)/255;
    }
    else{
        fMin = 0.0f;
        fMax = 1.0f;
    }
    
    LBGraphics::getInstance()->useProgram(program);
    glUniform1f(minColorUniform, fMin);
    glUniform1f(maxColorUniform, fMax);
}